package com.shujia.scala

object Demo15Fun2 {
  def main(args: Array[String]): Unit = {

    /**
      * 高阶函数
      * 1、以函数作为参数
      *
      */


    //fun需要一个 (参数为String 返回值为Int类型的函数) 作为参数
    def fun(f: String => Int): Unit = {

      //对传进来的函数做调用
      val i = f("100")

      println(i)
    }


    //参数为String 返回值为Int类型的函数
    def f1(str: String): Int = str.toInt

    def f2(str: String): Int = str.toInt + 1000


    //调用fun 需要传入一个参数为String  返回值为Int类型的函数
    fun(f1)

    fun(f2)


    /**
      * fun函数的类型
      * 参数类型： 参数是一个参数为String 返回值为Int类型的函数
      * 返回值：没有返回值
      *
      */
    val f3: (String => Int) => Unit = fun


    /**
      * lambda 表达式    -- 匿名函数
      *
      * (s: String) => s.toInt
      *
      * => 左边是参数
      * => 右边是返回值
      *
      */

    fun((s: String) => {
      s.toInt + 200
    })

    //大括号可以省略
    fun((s: String) => s.toInt)

    //可以自动推断参数的类型
    fun(s => s.toInt)

    //如果参数只使用了异常可以使用下划线代替
    fun(_.toInt)


    println("=" * 100)


    /**
      * 高阶函数的使用
      *
      */

    val array = Array(1, 2, 3, 4, 5, 6, 7, 8, 9)

    /**
      * foreach:  循环数组，按照顺序将数组中的元素一个一个传给后面的函数
      *
      */

    def f5(i: Int): Unit = println(i)

    array.foreach(f5)

    array.foreach((i: Int) => {
      //i代表的是数组中的元素
      print(i)
    })

    //省略类型
    array.foreach(i => print(i))

    //下划线代替变量
    array.foreach(println(_))


    //因为println是一个参数为Any 没有返回值的函数
    //foreach需要一个参数为Int没有返回值的函数
    // 同时Int是Any的子类
    //这里也可以使用多态
    //所以可以直接将println穿给foreach
    array.foreach(println)


  }

}
